﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using RBAC.MaHaiBo.Entity;
using RBAC.MaHaiBo.Repository.Interface;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;

namespace RBAC.MaHaiBo.Service
{
    public class MenuService : IMenuService
    {
        /// <summary>
        /// 日志
        /// </summary>
        ILogger<MenuService> logger;
        /// <summary>
        /// 角色菜单关联仓储
        /// </summary>
        IMenuRoleRepository mrRep;
        /// <summary>
        /// 角色仓储
        /// </summary>
        IRoleRepository rRep;
        /// <summary>
        /// 菜单仓储
        /// </summary>
        IMenuRepository mRep;
        /// <summary>
        /// 用户仓储
        /// </summary>
        IUserService uRep;
        /// <summary>
        /// 角色菜单关联仓储
        /// </summary>
        IUserRoleRepository urRep;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="logger">日志</param>
        /// <param name="mRep">菜单仓储</param>
        /// <param name="mrRep">角色菜单关联仓储</param>
        /// <param name="rRep">角色仓储</param>
        /// <param name="uRep">用户仓储</param>
        /// <param name="urRep">角色菜单关联仓储</param>
        public MenuService(ILogger<MenuService> logger, IMenuRepository mRep
            , IMenuRoleRepository mrRep,
             IUserService uRep,
             IUserRoleRepository urRep,
             IRoleRepository rRep)
        {
            this.logger = logger;
            this.mRep = mRep;
            this.mrRep = mrRep;
            this.uRep = uRep;
            this.urRep = urRep;
            this.rRep = rRep;
        }
        /// <summary>
        /// 添加菜单
        /// </summary>
        /// <param name="menu">要添加的数据</param>
        /// <returns>返回受影响行数</returns>
        public async Task<int> AddMenu(Menu menu)
        {
            try
            {
                var list = await mRep.GetAsync(p => p.MenuName == menu.MenuName && p.IsDeleted == false && p.Pid == menu.Pid);
                if (list.Count > 0)
                {
                    return -1;
                }
                return await mRep.AddAsync(menu);
            }
            catch (Exception ex)
            {
                logger.LogError("【菜单服务层】 添加菜单 出错" + ex.Message);
                throw;
            }
        }

        /// <summary>
        /// 查看省份有子菜单
        /// </summary>
        /// <param name="Mid"></param>
        /// <returns></returns>
        public async Task<int> MenuCount(int Mid)
        {
            try
            {
                var count = await mRep.GetAsync(p => p.Pid == Mid && !p.IsDeleted);
                return count.Count;
            }
            catch (Exception ex)
            {
                logger.LogError("【菜单服务层】 查看省份有子菜单 出错" + ex.Message);
                throw;
            }
        }

        /// <summary>
        /// 删除菜单信息
        /// </summary>
        /// <param name="Pid">要删除的菜单编号</param>
        /// <returns>返回受影响行数</returns>
        public async Task<int> DeleteMenu(int Mid)
        {
            try
            {
                var Mqouen = await mRep.GetModelAsync(Mid);
                if (Mqouen == null && Mqouen.IsDeleted == true)
                {
                    return 0;
                }
                await DeleteMenu1(Mqouen);
                return 1;
            }
            catch (Exception ex)
            {
                logger.LogError("【菜单服务层】 删除菜单信息 出错" + ex.Message);
                throw;
            }
        }
        /// <summary>
        /// 递归
        /// </summary>
        /// <param name="menu"></param>
        /// <returns></returns>
        public async Task DeleteMenu1(Menu menu)
        {
            menu.IsDeleted = true;
            await mRep.UpdateAsync(menu);
            var lisr = await mRep.GetAsync(p => p.Pid == menu.Mid);
            foreach (var item in lisr)
            {
                await DeleteMenu1(item);
            }
        }

        /// <summary>
        /// 显示全部菜单列表
        /// </summary>
        /// <returns>返回数据列表集合</returns>
        public async Task<FenYeDTO<MenuDTO>> GetAllMenuList(int poageiden, int pageSzen, string? Name)
        {
            try
            {
                  var fy=new FenYeDTO<MenuDTO>();
                var list = await mRep.GetAllAsync();
                var Mlist = (from  m in await mRep.GetAllAsync()
                             where m.IsDeleted == false
                             select new MenuDTO
                             {
                                 Mid = m.Mid,
                                 MenuName = m.MenuName,
                                 Url = m.Url,
                                 Pid = m.Pid,
                                 CreateBy = m.CreateBy,
                                 CreateDate = m.CreateDate,
                                 UpdateBy = m.UpdateBy,
                                 UpdateDate = m.UpdateDate,
                                 Pname = fandigui(m.Mid).Result
                             }).DistinctBy(p=>p.Mid);
                if (!string.IsNullOrEmpty(Name))
                {
                    Mlist = Mlist.Where(p => p.MenuName.Contains(Name));
                }
                fy.totyCount = Mlist.Count();
                fy.pageCount = (int)Math.Ceiling(fy.totyCount * 1.0 / pageSzen);
                fy.list = Mlist.OrderBy(p => p.Mid).Skip((poageiden - 1) * pageSzen).Take(pageSzen).ToList();
                return fy;
            }
            catch (Exception ex)
            {
                logger.LogError("【菜单服务层】 显示全部菜单列表 出错" + ex.Message);
                throw;
            }
        }

        /// <summary>
        /// 根据用户显示菜单列表（树形菜单列表）
        /// </summary>
        /// <returns>返回数据列表集合</returns>
        public async Task<List<Tmeen>> GetAllTmeenMenuList(int Uid)
        {
            try
            {
                var list = await mRep.GetAllAsync();
                var Mlist = (from ur in await urRep.GetAllAsync()
                             join r in await rRep.GetAllAsync()
                             on ur.Rid equals r.Rid
                             join mr in await mrRep.GetAllAsync()
                             on r.Rid equals mr.Rid
                             join m in await mRep.GetAllAsync()
                             on mr.Mid equals m.Mid
                             where m.IsDeleted == false && ur.Uid == Uid
                             select new MenuDTO
                             {
                                 Mid = m.Mid,
                                 MenuName = m.MenuName,
                                 Url = m.Url,
                                 Pid = m.Pid,
                                 CreateBy = m.CreateBy,
                                 CreateDate = m.CreateDate,
                                 UpdateBy = m.UpdateBy,
                                 UpdateDate = m.UpdateDate,
                                 Pname = fandigui(m.Mid).Result
                             }).DistinctBy(p => p.Mid).ToList();

                var mtlisy = GetMenu(Mlist, 0);

                return await mtlisy;
            }
            catch (Exception ex)
            {
                logger.LogError("【菜单服务层】 显示全部菜单列表 出错" + ex.Message);
                throw;
            }
        }


        /// <summary>
        /// 树形菜单列表
        /// </summary>
        /// <returns>返回数据集合</returns>
        public async Task<List<Tmeen>> GetMenu(List<MenuDTO> MenuDTO,int Pid)
        {
            try
            {
                var list = (from mlist in MenuDTO
                            where mlist.IsDeleted == false && mlist.Pid == Pid
                            select new Tmeen
                            {
                                id = mlist.Mid,
                                label = mlist.MenuName,
                                ULr = mlist.Url,
                                children = GetMenu(MenuDTO, mlist.Mid).Result
                            });
                return list.ToList();
            }
            catch (Exception ex)
            {
                logger.LogError("【角色菜单关联服务层】 树形菜单列表 出错" + ex.Message);
                throw;
            }
        }


        /// <summary>
        /// 显示父级列表
        /// </summary>
        /// <returns>返回 显示父级列表</returns>
        public async Task<List<Menu>> GetMenuList()
        {
            try
            {
                return await mRep.GetAsync(p => p.IsDeleted == false);
            }
            catch (Exception ex)
            {
                logger.LogError("【菜单服务层】 显示全部菜单列表 出错" + ex.Message);
                throw;
            }
        }

        /// <summary>
        /// 反填菜单信息
        /// </summary>
        /// <param name="Mid">菜单编号</param>
        /// <returns>返回菜单数据信息</returns>
        public async Task<Menu> GetMenuInfo(int Mid)
        {
            try
            {
                return await mRep.GetModelAsync(Mid);
            }
            catch (Exception ex)
            {
                logger.LogError("【菜单服务层】 反填菜单信息 出错" + ex.Message);
                throw;
            }
        }


        /// <summary>
        /// 修改菜单信息
        /// </summary>
        /// <param name="menu">修改后的数据信息</param>
        /// <returns>返回受影响行数</returns>
        public async Task<int> UpdateMenu(Menu menu)
        {
            try
            {
                var list = await mRep.GetAsync(p => p.MenuName == menu.MenuName && p.IsDeleted == false && p.Pid == menu.Pid);
                if (list.Count > 0)
                {
                    return -1;
                }
                menu.UpdateBy = "李四";
                menu.UpdateDate = DateTime.Now;
                return await mRep.UpdateAsync(menu);

            }
            catch (Exception ex)
            {
                logger.LogError("【菜单服务层】 修改菜单信息 出错" + ex.Message);
                throw;
            }
        }
        /// <summary>
        /// 父级
        /// </summary>
        /// <param name="Mid"></param>
        /// <returns></returns>
        public  async  Task<List<Menu>> fandigui(int Mid)
        {
            try
            {
                var list = await mRep.GetAllAsync();
                var clist= fandiguie(list, Mid);
                clist.RemoveAt(0);
                clist.Reverse();
                return clist.ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }
        /// <summary>
        /// 递归
        /// </summary>
        /// <param name="menus"></param>
        /// <param name="Mid"></param>
        /// <returns></returns>
        public static List<Menu> fandiguie(List<Menu> menus, int Mid)
        {
            var count = menus.Where(p => p.Mid == Mid);
            var result = new List<Menu>(count);
            foreach (var item in count)
            {
                result.AddRange(fandiguie(menus, item.Pid));
            }
            return result;
        }


    }
}
